6.1
使用 VTIME 设置驱动程序超时
play_again5.c
#include <stdio.h> #include <termios.h> /* #include <fcntl.h> */ #include <string.h> #define ASK "Do you want another transaction" #define TRIES 3 #define SLEEPTIME 2 #define BEEP putchar('\a') int get_response(char *, int); void tty_mode(int); void set_crmode(); void set_cr_noecho_mode(); /* void set_nodelay_mode(); */ char get_ok_char(); int main() { int response; tty_mode(0); /* save tty mode */ set_cr_noecho_mode(); /* set -icanon, -echo */ /* set_nodelay_mode(); */ response = get_response(ASK, TRIES); tty_mode(1); /* restore tty mode */ return response; } int get_response(char *question, int maxtries) { int input; printf("%s (y/n)?", question); while(1){ sleep(SLEEPTIME); input = tolower(get_ok_char()); if (input == 'y') return 0; if (input == 'n') return 1; if (maxtries-- == 0) return 2; BEEP; } } char get_ok_char() { int c; while ((c = getchar()) != EOF && strchr("yYnN", c) == NULL) ; return c; } void set_cr_noecho_mode() { struct termios ttystate; tcgetattr(0, &ttystate); ttystate.c_lflag &= ~ICANON; /* no buffering */ ttystate.c_lflag &= ~ECHO; /* no echo either */ ttystate.c_cc[VTIME] = 20; /* set timeout */ ttystate.c_cc[VMIN] = 0; tcsetattr(0, TCSANOW, &ttystate); } /* void set_nodelay_mode() */ /* { */ /* int termflags; */ /* termflags = fcntl(0, F_GETFL); */ /* termflags |= O_NDELAY; */ /* fcntl(0, F_SETFL, termflags); */ /* } */ void tty_mode(int how) { static struct termios original_mode; /* static int original_flags; */ if (how == 0){ /* tcgetattr(0, &original_mode); */ original_flags = fcntl(0, F_GETFL); } else{ /* tcsetattr(0, TCSANOW, &original_mode); */ fcntl(0, F_SETFL, original_flags); } }
6.5
#include <stdio.h> #include <ctype.h> #include <termios.h> #include <strings.h> #include <signal.h> void set_noecho_nodelay_mode(); void tty_mode(int); void cc_handle(int); int main() { int c; tty_mode(0); signal(SIGINT, cc_handle); signal(SIGQUIT, SIG_IGN); set_noecho_nodelay_mode(); while ((c = getchar()) != EOF){ if (c == 'Q'){ tty_mode(1); return 0; } if (c == 'z') c = 'a'; else if (islower(c)) c++; putchar(c); } return 0; } void cc_handle(int signum) { tty_mode(1); exit(1); } void set_noecho_nodelay_mode() { struct termios tty_set; tcgetattr(0, &tty_set); tty_set.c_lflag &= ~ICANON; tty_set.c_lflag &= ~ECHO; tty_set.c_cc[VTIME] = 20; tty_set.c_cc[VMIN] = 0; tcsetattr(0, TCSANOW, &tty_set); } void tty_mode(int mode) /* * mode == 0 : store mode * mode != 0 : restore mode */ { static struct termios tbuf; if (mode == 0){ tcgetattr(0, &tbuf); }else{ tcsetattr(0, TCSANOW, &tbuf); } }
6.6
#include <stdio.h> #include <ctype.h> #include <termios.h> #include <strings.h> #include <signal.h> void set_noecho_nodelay_mode(); void tty_mode(int); void cc_handle(int); void handle_char(char); int main() { int c; tty_mode(0); signal(SIGINT, cc_handle); signal(SIGQUIT, SIG_IGN); set_noecho_nodelay_mode(); while ((c = getchar()) != EOF){ /* printf("%d\n", c); */ handle_char(c); } return 0; } void kill_char() { putchar('\b'); putchar(' '); putchar('\b'); } void handle_char(char c) { static char buf[BUFSIZ]; static int i = 0; struct termios tb; tcgetattr(0, &tb); if (c == tb.c_cc[VERASE]){ kill_char(); i--; }else if (c == tb.c_cc[VWERASE]){ int j = 0; for (; i >= 0; i--, j++){ if (buf[i] == ' ' && j != 0){ break; }else{ kill_char(); } } }else if (c == tb.c_cc[VKILL]){ for (; i >= 0; i--){ kill_char(); } }else{ putchar(c); buf[i] = c; i++; } } void cc_handle(int signum) { tty_mode(1); exit(1); } void set_noecho_nodelay_mode() { struct termios tty_set; tcgetattr(0, &tty_set); tty_set.c_lflag &= ~ICANON; tty_set.c_lflag &= ~ECHO; tty_set.c_cc[VMIN] = 1; tcsetattr(0, TCSANOW, &tty_set); } void tty_mode(int mode) /* * mode == 0 : store mode * mode != 0 : restore mode */ { static struct termios tbuf; if (mode == 0){ tcgetattr(0, &tbuf); }else{ tcsetattr(0, TCSANOW, &tbuf); } }